package gui;

import interfaces.LoginObserver;
import interfaces.LoginSubject;

import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

import domain.LoginInfo;

import application.LoginObserverImpl;

public class LoginWindow extends JDialog implements ActionListener, LoginSubject {
	private static final long serialVersionUID = -3645391403723119862L;

	private JTextField name;

	private JPasswordField password;

	private JButton bLogin;

	private JButton bCancel;	
	
	private ArrayList<LoginObserver> observers; 
	public LoginWindow()  {
		super();
		this.toFront();
		observers = new ArrayList();

		// get database connection
		setTitle("Login Window");

		getContentPane().setLayout(new BorderLayout());
		getContentPane().add(makeLoginPanel(), "Center");
		getContentPane().add(makeButtonPanel(), "South");

		pack();
		setResizable(false);
		setLocationRelativeTo(null);
		setVisible(true);

	}

	private JPanel makeLoginPanel() {
		JPanel loginPanel = new JPanel();
		JLabel label;

		loginPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 0, 20));

		GridBagLayout gbl = new GridBagLayout();
		GridBagConstraints gbc = new GridBagConstraints();

		loginPanel.setLayout(gbl);
		gbc.weightx = 1.0;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.insets = new Insets(0, 5, 10, 5);
		gbc.gridx = 0;
		gbc.gridy = 0;
		label = new JLabel("Login:", SwingConstants.LEFT);
		gbl.setConstraints(label, gbc);
		loginPanel.add(label);
		gbc.gridx = 1;
		name = new JTextField("", 10);
		
		gbl.setConstraints(name, gbc);
		loginPanel.add(name);

		gbc.gridx = 0;
		gbc.gridy = 1;
		label = new JLabel("Password:", SwingConstants.LEFT);
		gbl.setConstraints(label, gbc);
		loginPanel.add(label);
		gbc.gridx = 1;
		password = new JPasswordField("", 10);
		
		gbl.setConstraints(password, gbc);
		loginPanel.add(password);

		return loginPanel;
	}

	private JPanel makeButtonPanel() {
		JPanel buttonPanel = new JPanel();

		buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

		// make LogIn button
		bLogin = new JButton("Login");
		bLogin.setActionCommand("Login");
		buttonPanel.add(bLogin);
		rootPane.setDefaultButton(bLogin);
		bLogin.addActionListener(this);
		this.getRootPane().setDefaultButton(bLogin);

		// make Cancel button
		bCancel = new JButton("Cancel");
		bCancel.setActionCommand("Cancel");
		buttonPanel.add(bCancel);
		bCancel.addActionListener(this);
		
		return buttonPanel;
	}

	
	

	

	/**
	 * This method controls the cursor for login window. If isWait is set to
	 * true, dialog's cursor is set to Cursor.WAIT_CURSOR. If isWait is set to
	 * false, the cursor is set ta Deafult. While the window is in WAIT mode,
	 * this method will also disable Login and Cancel buttons to ensure the user
	 * does not accidently request a cancel while loging in or launching a
	 * second login.
	 */
	private void setWaitCursor(boolean isWait) {
		/*
		 * In order to disable login and cancel buttons while logging in to the
		 * application, this method will temporarely change action commands and
		 * reset them when login process failed to give user another chance.
		 * Note: Disabling the buttons by calling setEnabled(false) did not work
		 * since login() method is called from an action event handler and the
		 * process will not be released to AWT until login method is complete.
		 * Using invokeLater() around the login() method did not have any effect
		 * either.
		 */
		if (isWait) {
			this.getGlassPane().setCursor(new Cursor(Cursor.WAIT_CURSOR));
			this.getGlassPane().setVisible(true);
			bLogin.setActionCommand("none");
			bCancel.setActionCommand("none");
		} else {
			this.getGlassPane().setCursor(Cursor.getDefaultCursor());
			this.getGlassPane().setVisible(false);
			bLogin.setActionCommand("Login");
			bCancel.setActionCommand("Cancel");
		}
	}

	public void actionPerformed(ActionEvent e) {
		JButton btn = (JButton) e.getSource();
		
		if (btn.getActionCommand().equals("Login")) {
			// Because login() process happens before swing process (above),
			// force it to happen "later"
			SwingUtilities.invokeLater(new Runnable() {
				public void run() {
					setWaitCursor(true);					
					notifyObservers();
					setWaitCursor(false);
				}
			});
		} else if (btn.getActionCommand().equals("Cancel")) {
			System.exit(0);
		}
		
	}

	public void attachObserver(LoginObserver observer) {
		observers.add(observer);
		
	}

	public void detachObserver(LoginObserver observer) {
		observers.remove(observer);
		
	}

	public void notifyObservers() {
		LoginInfo info = new LoginInfo(name.getText(),new String(password.getPassword()));
		for (LoginObserver  observer : observers) {			
			observer.update(info);
		}
		
	}
	

}
